﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BLL;
using Exceptions;
using BTO;

namespace CentralReserva
{
    public class MenuTiposAlojamento
    {
        private static int opcao = 0;

        public static void menuTiposAlojamento()
        {
            do
            {
                Console.WriteLine("Menu Tipos de Alojamento: Escolha uma das opçoes disponiveis.\n\n");
                Console.WriteLine(" 1 - Registar tipo de alojamento - permite o registo de novos tipos;\n" +
                                  " 2 - Consultar tipo de alojamento - consultar, editar e eliminar tipos;\n" +

                                  " 0 - Voltar ao menu principal;\n");

                string aux = Console.ReadLine();
                if (int.TryParse(aux, out opcao))
                {
                    Console.WriteLine("\n");
                    switch (opcao)
                    {
                        case 1:
                            Console.Clear();
                            registarTipoAlojamento();
                            break;
                        case 2:
                            Console.Clear();
                            menuConsultarTiposAlojamento();
                            break;
                        case 0:
                            Console.Clear();
                            MenuPrincipal.menuPrincipal();
                            break;
                        default:
                            Console.Clear();
                            Console.WriteLine("Introduza a uma opcao valida. [0-2]\n");
                            break;
                    }
                }
                else
                {
                    opcao = -1;
                    Console.Clear();
                    Console.WriteLine("Por favor introduza apenas numeros.\n");
                }
            } while (opcao != 0);
        }

        private static void registarTipoAlojamento()
        {
            BTO.TipoAlojamento tipo = new BTO.TipoAlojamento();
            try
            {
                Console.Write("Descricao do tipo de alojamento: ");
                string descricao = Console.ReadLine();

                Console.WriteLine("\nA escrever na base de dados. . . \n");

                tipo.descricao = descricao;

                BLLTipoAlojamento novoTipo = new BLLTipoAlojamento();

                novoTipo.insert(tipo);

                Console.WriteLine("Novo tipo de alojamento registado com sucesso!\n");
            }
            catch (DescricaoTipoAlojamentoException e)
            {
                Console.WriteLine(e.Message + "\n");
                Console.Write("Pretende introduzir novamente? (y/n)\n ");
                string resposta = Console.ReadLine();
                if (resposta == "y" || resposta == "Y" || resposta == "yes" || resposta == "Yes")
                {
                    Console.Write("Introduza novamente a descricao:\n ");
                    string descricao = Console.ReadLine();
                    tipo.descricao = descricao;

                    Console.WriteLine("\nA escrever na base de dados. . . \n");
                    registarTipoAlojamento(tipo);

                }
                else
                {
                    menuTiposAlojamento();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message + "\n");
            }

            menuTiposAlojamento();
        }

        private static void registarTipoAlojamento(BTO.TipoAlojamento tipoAlojamento)
        {
            try
            {
                BLLTipoAlojamento novoTipo = new BLLTipoAlojamento();
                novoTipo.insert(tipoAlojamento);
            }
            catch (DescricaoTipoAlojamentoException e)
            {
                Console.WriteLine(e.Message + "\n");
                Console.Write("Pretende introduzir novamente? (y/n)\n ");
                string resposta = Console.ReadLine();
                if (resposta == "y" || resposta == "Y" || resposta == "yes" || resposta == "Yes")
                {
                    Console.Write("Introduza novamente a descricao:\n ");
                    string descricao = Console.ReadLine();
                    tipoAlojamento.descricao = descricao;
                    registarTipoAlojamento(tipoAlojamento);
                    Console.WriteLine("Novo tipo de alojamento registado com sucesso!\n");
                }
                else
                {
                    menuTiposAlojamento();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message + "\n");
            }

            menuTiposAlojamento();
        }

        private static void menuConsultarTiposAlojamento()
        {
            do
            {
                opcao = 0;
                Console.WriteLine("Menu de consulta e gestao de tipos de alojamento, \nescolha uma das operacoes:\n\n");
                Console.WriteLine(" 1 - Listar todas os tipos registados;\n" +
                                  " 2 - Listar por id;\n" +
                                  " 3 - Listar por descricao;\n" +
                                  " 0 - Voltar ao Menu Tipos de Alojamento;\n");

                string aux = Console.ReadLine();
                if (int.TryParse(aux, out opcao))
                {
                    Console.WriteLine("\n");
                    switch (opcao)
                    {
                        case 1:
                            Console.Clear();
                            listarTiposAlojamento();
                            break;
                        case 2:
                            Console.Clear();
                            listarTiposAlojamentoPorId();
                            break;
                        case 3:
                            Console.Clear();
                            listarTiposAlojamentoPorDescricao();
                            break;
                        case 0:
                            Console.Clear();
                            menuTiposAlojamento();
                            break;
                        default:
                            Console.WriteLine("Introduza a uma opcao valida. [0-3]\n");
                            break;
                    }
                }
                else
                {
                    opcao = -1;
                    Console.Clear();
                    Console.WriteLine("Por favor introduza apenas numeros.\n");
                }
            } while (opcao != 0);
        }

        private static void listarTiposAlojamento()
        {

            Console.WriteLine("Lista dos tipos de alojamento registados: \n\n");
            Console.WriteLine("A carregar lista . . .\n");
            BLLTipoAlojamento tipoAlojamento = new BLLTipoAlojamento();
            try
            {
                List<BTO.TipoAlojamento> listTipos = tipoAlojamento.list();
                Console.WriteLine("Lista ok!\n\n");

                int counter = 1;
                foreach (BTO.TipoAlojamento tipo in listTipos)
                {
                    Console.WriteLine("\n\n" + counter + ": ");
                    Console.WriteLine(tipo);
                    counter++;
                }
            }
            catch (NotFoundTipoAlojamentoException ex)
            {
                Console.WriteLine(ex.Message + "\n\n");
            }
            Console.WriteLine("\n\nQuando desejar pressione \"enter\" para voltar ao menu de gestao de tipos de alojamento.");

            //Listener para averiguar se o utilizador pressiona enter
            ConsoleKeyInfo keyHit = new ConsoleKeyInfo();
            keyHit = Console.ReadKey(true);

            if (keyHit.Key == ConsoleKey.Enter) { Console.Clear(); menuConsultarTiposAlojamento(); }
        }

        private static void listarTiposAlojamentoPorId()
        {

            Console.WriteLine("Apos seleccionar o tipo de alojamento, vai poder efectuar operacoes sobre o mesmo.\n");
            Console.Write("Introduza o id do tipo de alojamento que procura: ");
            int id = -1;
            String aux = Console.ReadLine();

            if (int.TryParse(aux, out id))
            {
                Console.WriteLine("\nA procurar . . .\n");
                BLLTipoAlojamento tipoAlojamento = new BLLTipoAlojamento();

                try
                {
                    Console.WriteLine(tipoAlojamento.getByID(id));
                    Console.WriteLine("\n");
                    operarSobreTiposAlojamento(tipoAlojamento.getByID(id));
                    menuConsultarTiposAlojamento();
                }
                catch (NotFoundTipoAlojamentoException ex)
                {

                    Console.WriteLine("\n" + ex.Message + " Por favor verifique o id do tipo de alojamento e introduza novamente.\n\n");
                    Console.WriteLine("Prefere sair para o menu anterior? (y/n)");
                    string resposta = Console.ReadLine();
                    if (resposta == "y" || resposta == "Y" || resposta == "yes" || resposta == "Yes")
                    {
                        Console.Clear();
                        menuConsultarTiposAlojamento();
                    }
                    else
                    {
                        Console.Clear();
                        listarTiposAlojamentoPorId();
                    }
                }

            }
            else
            {
                Console.WriteLine("\nAtencao o id apenas pode conter numeros inteiros.\n");
                Console.WriteLine("\nPor favor volte a introduzir o id.\n\n\n");
                listarTiposAlojamentoPorId();
            }

        }

        private static void listarTiposAlojamentoPorDescricao()
        {

            Console.WriteLine("Apos seleccionar o tipo de alojamento, vai poder efectuar operacoes sobre o mesmo.\n");
            Console.Write("Introduza a descricao do tipo de alojamento que procura: ");
            String descricao = Console.ReadLine();
            Console.WriteLine("\nA procurar . . .\n");
            BLLTipoAlojamento tipoAlojamento = new BLLTipoAlojamento();

            try
            {
                Console.WriteLine(tipoAlojamento.getByDescricao(descricao));
                Console.WriteLine("\n");
                operarSobreTiposAlojamento(tipoAlojamento.getByDescricao(descricao));
                menuConsultarTiposAlojamento();
            }
            catch (NotFoundTipoAlojamentoException ex)
            {

                Console.WriteLine("\n" + ex.Message + " Por favor verifique a descricao do tipo de alojamento e introduza novamente.\n\n");
                Console.WriteLine("Prefere sair para o menu anterior? (y/n)");
                string resposta = Console.ReadLine();
                if (resposta == "y" || resposta == "Y" || resposta == "yes" || resposta == "Yes")
                {
                    Console.Clear();
                    menuConsultarTiposAlojamento();
                }
                else
                {
                    Console.Clear();
                    listarTiposAlojamentoPorDescricao();
                }
            }
        }

        private static void operarSobreTiposAlojamento(BTO.TipoAlojamento tipoAlojamento)
        {
            do
            {
                opcao = 0;
                Console.WriteLine("Menu de gestao do tipo de alojamento " + tipoAlojamento.descricao + ", escolha uma das operacoes:\n\n");
                Console.WriteLine(" 1 - Editar informacoes do tipo de alojamento;\n" +
                                  " 2 - Eliminar o tipo de alojamento;\n" +
                                  " 0 - Voltar ao menu de consulta e gestao;\n");

                string aux = Console.ReadLine();
                if (int.TryParse(aux, out opcao))
                {
                    Console.WriteLine("\n");
                    switch (opcao)
                    {
                        case 1:
                            Console.Clear();
                            actualizarTipoAlojamento(tipoAlojamento);
                            break;
                        case 2:
                            Console.Clear();
                            eliminarTipoAlojamento(tipoAlojamento);
                            break;
                        case 0:
                            Console.Clear();
                            menuConsultarTiposAlojamento();
                            break;
                        default:
                            Console.WriteLine("Introduza a uma opcao valida. [0-2]\n");
                            break;
                    }
                }
                else
                {
                    opcao = -1;
                    Console.Clear();
                    Console.WriteLine("Por favor introduza apenas numeros.\n");
                }
            } while (opcao != 0);
        }

        private static void actualizarTipoAlojamento(BTO.TipoAlojamento toUpdate)
        {
            Console.WriteLine("Edicao e actualizacao dos dados do tipo de alojamento " + toUpdate.descricao + ".\n");
            Console.WriteLine("A esquerda é fornecida a informacao actual;");
            Console.WriteLine("Do lado direito pode editar a informacao, ou manter a antiga.\n\n");

            BLLTipoAlojamento tipoAlojamento = new BLLTipoAlojamento();
            BTO.TipoAlojamento oldTipoAlojamento = toUpdate;
            BTO.TipoAlojamento newTipoAlojamento = new BTO.TipoAlojamento();

            newTipoAlojamento.IDTipoAlojamento = oldTipoAlojamento.IDTipoAlojamento;

            Console.Write("Descricao (" + oldTipoAlojamento.descricao + "): ");
            string newDescricao = Console.ReadLine();
            if (newDescricao == "")
                newTipoAlojamento.descricao = oldTipoAlojamento.descricao;
            else
                newTipoAlojamento.descricao = newDescricao;

            try
            {
                Console.WriteLine("Tem a certeza que pretende alterar o registo do tipo de alojamento " + oldTipoAlojamento.descricao + "? (y/n)");
                string resposta = Console.ReadLine();
                if (resposta == "y" || resposta == "Y" || resposta == "yes" || resposta == "Yes")
                {
                    Console.WriteLine("\nA alterar . . .\n");
                    tipoAlojamento.update(newTipoAlojamento);
                    Console.WriteLine("Dados do tipo de alojamento alterados com sucesso!\n\n");
                    operarSobreTiposAlojamento(newTipoAlojamento);
                }
            }
            catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine(newTipoAlojamento); operarSobreTiposAlojamento(oldTipoAlojamento); }
            operarSobreTiposAlojamento(oldTipoAlojamento);
        }

        private static void eliminarTipoAlojamento(BTO.TipoAlojamento toDelete)
        {
            Console.WriteLine("Tem a certeza que pretende eliminar o registo do tipo de alojamento " + toDelete.descricao + "? (y/n)");
            string resposta = Console.ReadLine();
            if (resposta == "y" || resposta == "Y" || resposta == "yes" || resposta == "Yes")
            {
                Console.WriteLine("\nA eliminar . . .\n");
                BLLTipoAlojamento tipoAlojamento = new BLLTipoAlojamento();
                tipoAlojamento.delete(toDelete.IDTipoAlojamento);
                Console.WriteLine("Tipo de alojamento eliminado com sucesso!\n\n");
                menuConsultarTiposAlojamento();
            }
            operarSobreTiposAlojamento(toDelete);
        }
    }
}
